/*!
 * @file       apm32f10x_emmc.h
 *
 * @brief      This file contains all the functions prototypes for the EMMC firmware library
 *
 * @version    V1.0.0
 *
 * @date       2019-8-6
 *
 */


#ifndef __APM32F10x_EMMC_H
#define __APM32F10x_EMMC_H

#ifdef __cplusplus
extern "C" {
#endif 

#include "apm32f10x.h"

/**
 * @brief EMMC NORSRAM_Bank  
 */
typedef enum 
{
  EMMC_Bank1_NORSRAM1 = 0x00000000,
  EMMC_Bank1_NORSRAM2 = 0x00000002,
  EMMC_Bank1_NORSRAM3 = 0x00000004,
  EMMC_Bank1_NORSRAM4 = 0x00000006
}EMMC_Bank_NORSRAM_T;

/**
 * @brief EMMC NORSRAM_Bank  
 */
typedef enum 
{
  EMMC_Bank2_NAND = 0x00000010,
  EMMC_Bank3_NAND = 0x00000100,
  EMMC_Bank4_PCCARD = 0x00001000
}EMMC_Bank_NAND_T;

/**
 * @brief EMMC_Data_Address_Bus_Multiplexing 
 */
typedef enum 
{
  EMMC_DataAddressMux_Disable = 0x00000000,
  EMMC_DataAddressMux_Enable = 0x00000002
}EMMC_DataAddressMux_T;

/**
 * @brief EMMC_Memory_Type 
 */
typedef enum
{
  EMMC_MEMORYTYPE_SRAM = 0x00000000,
  EMMC_MEMORYTYPE_PARAM = 0x00000004,
  EMMC_MEMORYTYPE_NOR = 0x00000008
}EMMC_MEMORY_TYPE_T;

/**
 * @brief EMMC_Data_Width 
 */
typedef enum 
{
  EMMC_MEMORY_DATA_WIDTH_8b = 0x00000000,
  EMMC_MEMORY_DATA_WIDTH_16b = 0x00000010
}EMMC_DATA_WIDTH_T;

/**
 * @brief EMMC_Burst_Access_Mode 
 */
typedef enum 
{
  EMMC_BURST_ACCESS_MODE_DISABLE = 0x00000000,
  EMMC_BURST_ACCESS_MODE_ENABLE = 0x00000100
}EMMC_BURST_ACCESS_MODE_T;

/**
 * @brief EMMC_AsynchronousWait 
 */
typedef enum 
{
  EMMC_ASYNCHRONOUSWAIT_DISABLE = 0x00000000,
  EMMC_ASYNCHRONOUSWAIT_ENABLE = 0x00008000
}EMMC_ASYNCHRONOUSWAIT_T;

/**
 * @brief EMMC_Wait_Signal_Polarity 
 */
typedef enum 
{
  EMMC_WAIT_SIGNAL_POLARITY_LOW = 0x00000000,
  EMMC_WAIT_SIGNAL_POLARITY_HIGH = 0x00000200
}EMMC_WAIT_SIGNAL_POLARITY_T;

/**
 * @brief EMMC_Wrap_Mode 
 */
typedef enum 
{
  EMMC_WRAP_MODE_DISABLE = 0x00000000,
  EMMC_WRAP_MODE_ENABLE = 0x00000400
}EMMC_WRAP_MODE_T;

/**
 * @brief EMMC_Wait_Timing 
 */
typedef enum 
{
  EMMC_WAIT_SIGNAL_ACTIVE_BEFOREWAITSTATE = 0x00000000,
  EMMC_WAIT_SIGNAL_ACTIVE_DURINGWAITSTATE = 0x00000800
}EMMC_WAIT_SIGNAL_ACTIVE_T;

/**
 * @brief EMMC_Write_Operation 
 */
typedef enum 
{
  EMMC_WRITE_OPERATION_DISABLE = 0x00000000,
  EMMC_WRITE_OPERATION_ENABLE = 0x00001000
}EMMC_WRITE_OPERATION_T;

/**
 * @brief EMMC_Wait_Signal 
 */
typedef enum 
{
  EMMC_WAITE_SIGNAL_DISABLE = 0x00000000,
  EMMC_WAITE_SIGNAL_ENABLE = 0x00002000
}EMMC_WAITE_SIGNAL_T;

/**
 * @brief EMMC_Extended_Mode 
 */
typedef enum 
{
  EMMC_EXTENDEN_MODE_DISABLE = 0x00000000,
  EMMC_EXTENDEN_MODE_ENABLE = 0x00004000
}EMMC_EXTENDEN_MODE_T;

/**
 * @brief EMMC_Write_Burst 
 */
typedef enum 
{
  EMMC_WRITE_BURST_DISABLE = 0x00000000,
  EMMC_WRITE_BURST_ENABLE = 0x00080000
}EMMC_WRITE_BURST_T;

/**
 * @brief EMMC_NAND_Bank  
 */
typedef enum 
{
  EMMC_NAND_Bank2 = 0x00000010,
  EMMC_NAND_Bank3 = 0x00000100
}EMMC_NAND_Bank_T;

/**
 * @brief   EMMC_WAIT_FEATURE
 */
typedef enum 
{
  EMMC_WAIT_FEATURE_DISABLE = 0x00000000,
  EMMC_WAIT_FEATURE_ENABLE = 0x00000002
}EMMC_WAIT_FEATURE;

/**
 * @brief EMMC_ECC  
 */
typedef enum 
{
  EMMC_ECC_DISABLE = 0x00000000,
  EMMC_ECC_ENABLE = 0x00000040
}EMMC_ECC_T;

/**
 * @brief EMMC_ECC_Page_Size  
 */
typedef enum 
{
  EMMC_ECC_PAGE_SIZE_256Bytes  = 0x00000000,
  EMMC_ECC_PAGE_SIZE_512Bytes  = 0x00020000,
  EMMC_ECC_PAGE_SIZE_1024Bytes = 0x00040000,
  EMMC_ECC_PAGE_SIZE_2048Bytes = 0x00060000,
  EMMC_ECC_PAGE_SIZE_4096Bytes = 0x00080000,
  EMMC_ECC_PAGE_SIZE_8192Bytes = 0x000A0000
}EMMC_ECC_PAGE_SIZE;

/**
 * @brief EMMC_Access_Mode  
 */
typedef enum 
{
  EMMC_Access_Mode_A = 0x00000000,
  EMMC_Access_Mode_B = 0x10000000,
  EMMC_Access_Mode_C = 0x20000000,
  EMMC_Access_Mode_D = 0x30000000
}EMMC_Access_Mode;


/**
 * @brief  EMMC_Interrupt_sources 
 */
typedef enum 
{
  EMMC_INT_RisingEdge = 0x00000008,
  EMMC_INT_Level = 0x00000010,
  EMMC_INT_FallingEdge = 0x00000020
}EMMC_INT_T;

/**
 * @brief  EMMC_Flags 
 */
typedef enum 
{
  EMMC_FLAG_RisingEdge = 0x00000001,
  EMMC_FLAG_Level = 0x00000002,
  EMMC_FLAG_FallingEdge = 0x00000004,
  EMMC_FLAG_FEMPT = 0x00000040
}EMMC_FLAG_T;

/**
 * @brief Timing parameters For NOR/SRAM Banks    
 */
typedef struct 
{
  uint32_t EMMC_ADDRESS_SETUP_TIME;      
  
  uint32_t EMMC_ADDRESS_HOLD_TIME;        
  
  uint32_t EMMC_DATA_SETUP_TIME;
  
  uint32_t EMMC_BUS_TURN_AROUND_DURATION;
  
  uint32_t EMMC_CLK_DIVISION;
  
  uint32_t EMMC_DATA_LATENCY;
  
  uint32_t EMMC_ACCESS_MODE;
  
}EMMC_NORSRAMTimingInit_T;


typedef struct 
{
  EMMC_Bank_NORSRAM_T EMMC_Bank;
  
  EMMC_DataAddressMux_T EMMC_DataAddressMux;
  
  EMMC_MEMORY_TYPE_T EMMC_MemoryType;
  
  EMMC_DATA_WIDTH_T EMMC_MemoryDataWidth;
  
  EMMC_BURST_ACCESS_MODE_T EMMC_BurstAcceesMode;
  
  EMMC_ASYNCHRONOUSWAIT_T EMMC_AsynchronousWait;
  
  EMMC_WAIT_SIGNAL_POLARITY_T EMMC_WaitSignalPolarity;
  
  EMMC_WRAP_MODE_T EMMC_WrapMode;
  
  EMMC_WAIT_SIGNAL_ACTIVE_T EMMC_WAIT_SIGNAL_ACTIVE;
  
  EMMC_WRITE_OPERATION_T EMMC_WriteOperation;
  
  EMMC_WAITE_SIGNAL_T EMMC_WaiteSignal;
  
  EMMC_EXTENDEN_MODE_T EMMC_ExtendedMode;
  
  EMMC_WRITE_BURST_T EMMC_WriteBurst;
  
  EMMC_NORSRAMTimingInit_T* EMMC_ReadWriteTimingStruct;
  
  EMMC_NORSRAMTimingInit_T* EMMC_WriteTimingStruct;
  
}EMMC_NORSRAMConfig_T;


typedef struct 
{
  uint32_t EMMC_SetupTime;
  
  uint32_t EMMC_WaitSetupTime;
  
  uint32_t EMMC_HoldSetupTime;
  
  uint32_t EMMC_HiZSetupTime;
  
}EMMC_NAND_PCCARDTimingConfig_T;


typedef struct 
{
  EMMC_NAND_Bank_T EMMC_Bank;
  
  EMMC_WAIT_FEATURE EMMC_Waitfeature;
  
  EMMC_DATA_WIDTH_T EMMC_MemoryDataWidth;
  
  EMMC_ECC_T EMMC_ECC;
  
  EMMC_ECC_PAGE_SIZE EMMC_ECCPageSize;
  
  uint32_t EMMC_TCLRSetupTime;
  
  uint32_t EMMC_TARSetupTime;
  
  EMMC_NAND_PCCARDTimingConfig_T* EMMC_CommonSpaceTiming_T;
  
  EMMC_NAND_PCCARDTimingConfig_T* EMMC_AttributeSpaceTiming_T;
  
}EMMC_NANDConfig_T;

typedef struct 
{
  EMMC_WAIT_FEATURE EMMC_Waitfeature;
  
  uint32_t EMMC_TCLRSetupTime;
  
  uint32_t EMMC_TARSetupTime;
  
  EMMC_NAND_PCCARDTimingConfig_T* EMMC_CommonSpaceTiming_T;
  
  EMMC_NAND_PCCARDTimingConfig_T* EMMC_AttributeSpaceTiming_T;
  
  EMMC_NAND_PCCARDTimingConfig_T* EMMC_IOSpaceTiming_T;
}EMMC_PCCARDConfig_T;

/*  Function used to set the EMMC configuration to the default reset state *****/
void EMMC_NORSRAMRest(EMMC_Bank_NORSRAM_T EMMC_Bank);
void EMMC_NANDRest(EMMC_Bank_NAND_T EMMC_Bank);
void EMMC_PCCARDRest(void);

/* Initialization and Configuration functions *********************************/
void EMMC_NORSRAMConfig(EMMC_NORSRAMConfig_T* EMMC_NORSRAMConfigStruct);
void EMMC_NANDConfig(EMMC_NANDConfig_T* EMMC_NANDConfigStruct);
void EMMC_PCCARDConfig(EMMC_PCCARDConfig_T* EMMC_PCCARDConfigStruct);
void EMMC_NORSRAMStructConfig(EMMC_NORSRAMConfig_T* EMMC_NORSRAMConfigStruct);
void NANDStructConfig(EMMC_NANDConfig_T* EMMC_NANDConfigStruct);
void EMMC_PCCARDStructConfig(EMMC_PCCARDConfig_T* EMMC_PCCARDConfigStruct);
void EMMC_NORSRAMEnable(EMMC_Bank_NORSRAM_T EMMC_Bank);
void EMMC_NORSRAMDisable(EMMC_Bank_NORSRAM_T EMMC_Bank);
void EMMC_NANDEnable(EMMC_Bank_NAND_T EMMC_Bank);
void EMMC_NANDDisable(EMMC_Bank_NAND_T EMMC_Bank);
void EMMC_NANDECCEnable(EMMC_Bank_NAND_T EMMC_Bank);
void EMMC_NANDECCDisable(EMMC_Bank_NAND_T EMMC_Bank);
uint32_t EMMC_ReadECC(EMMC_Bank_NAND_T EMMC_Bank);

/* flags and Int management functions **********************************/
void EMMC_IntEnable(EMMC_Bank_NAND_T EMMC_Bank, EMMC_INT_T EMMC_Int);
void EMMC_IntDisable(EMMC_Bank_NAND_T EMMC_Bank, EMMC_INT_T EMMC_Int);
uint16_t EMMC_ReadFlagStatus(EMMC_Bank_NAND_T EMMC_Bank, EMMC_FLAG_T EMMC_flag);
void EMMC_ClearFlag(EMMC_Bank_NAND_T EMMC_Bank, EMMC_FLAG_T EMMC_flag);
uint16_t EMMC_ReadIntFlag(EMMC_Bank_NAND_T EMMC_Bank, EMMC_INT_T EMMC_Int);
void EMMC_ClearIntFlag(EMMC_Bank_NAND_T EMMC_Bank, EMMC_INT_T EMMC_Int);

#ifdef __cplusplus
}
#endif

#endif /* __APM32F10x_EMMC_H */
